                                                                     
                                                                     
                                                                     
                                             
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
public class PCEContext {	
	int principleClassesCount=0;
	int defaultRows=100000;
	int defaultColumns=10000;
	String [ ]PrincipleClassNames;
	int [ ]PCNoOfMethods;
	int [ ]PCNoOfAttribute;
	String [ ][ ]PCMethods;
	String [ ][ ]PCAttributes;
	String [][]association;
	int noOfRows=0;
	int noOfColumns=0;
	String explorer="null";
	int currentIndex=0;
	String extension="null";
	String viewType="null";
public void extractInfo() throws Exception{	
    
    principleClassesCount=countNoOfPrincipalClasses();
    PrincipleClassNames=new String[principleClassesCount];
    PCNoOfMethods=new int[principleClassesCount];
    PCNoOfAttribute=new int[principleClassesCount];
    PCMethods=new String[principleClassesCount][1000];
    PCAttributes=new String[principleClassesCount][1000];
}	
public void getPrincipleClassAttributes(String FileName) throws Exception{

	int count=0;
	FileInputStream fstreamForPrincipleClass;
	fstreamForPrincipleClass = new FileInputStream("InfoFiles/"+FileName);
	DataInputStream inForPrincipleClass = new DataInputStream(fstreamForPrincipleClass);
	BufferedReader brPrincipleClass = new BufferedReader(new InputStreamReader(inForPrincipleClass));
	int attributeCount=0;	
	for(int i=0; i<principleClassesCount; i++){
		PCNoOfAttribute[i]=0;
	}

	String Stmt=brPrincipleClass.readLine();
	if(Stmt!=null){
		Stmt=brPrincipleClass.readLine();
	}
	 while (Stmt != null){
	
		 if(Stmt.contentEquals("EndOfClass") ){
			 Stmt=brPrincipleClass.readLine(); //Read Next Class Name
			 count++;
			
			 attributeCount=0;
			 
		 }
		 else if(Stmt.contentEquals("StartOfMethod")){
			 Stmt=brPrincipleClass.readLine(); //Read Method Name			 
			 
		 }
		 else if(!Stmt.contentEquals("EndOfMethod") ){
			 boolean isAlreadyExits=false;
			 for(int j=0; j<attributeCount;j++){
				 if(PCAttributes[count][j].contentEquals(Stmt)){
					isAlreadyExits=true; 
				 } 
			 }
			 if(!isAlreadyExits){		
			
				 PCAttributes[count][attributeCount++]=Stmt;
				 PCNoOfAttribute[count]++;	
			 }
			 		 	
		 }
		 if(Stmt!=null)
		 {
			 Stmt=brPrincipleClass.readLine();
		 } 
	}	 
 	inForPrincipleClass.close();


	
}
public int countNoOfPrincipalClasses() throws IOException{

	int count=0;
	
    FileInputStream fstreamForPrincipleClass;
	fstreamForPrincipleClass = new FileInputStream("InfoFiles/PrincipleClassGroup.txt");
	DataInputStream inForPrincipleClass = new DataInputStream(fstreamForPrincipleClass);
	BufferedReader brPrincipleClass = new BufferedReader(new InputStreamReader(inForPrincipleClass));
	String Stmt=brPrincipleClass.readLine();
	 while (Stmt != null){
		 if(Stmt.contentEquals("EndOfClass")){			 
			 count++;
		 }
		 Stmt=brPrincipleClass.readLine();
	}	 
 	inForPrincipleClass.close();
    return count;
    
}
public void getPrincipleClassNamesAndMethods() throws IOException{
	
	int count=0;
	int methodCount=0;	
	int principleClassNo=0;
	for(int i=0; i<principleClassesCount; i++){
		PCNoOfMethods[i]=0;
	}
	
    FileInputStream fstreamForPrincipleClass;
	fstreamForPrincipleClass = new FileInputStream("InfoFiles/PrincipleClassGroup.txt");
	DataInputStream inForPrincipleClass = new DataInputStream(fstreamForPrincipleClass);
	BufferedReader brPrincipleClass = new BufferedReader(new InputStreamReader(inForPrincipleClass));
	
	String Stmt=brPrincipleClass.readLine();
	 if(Stmt != null ){
		 
		 PrincipleClassNames[count++]=Stmt;
		 
		 while((Stmt=brPrincipleClass.readLine())!=null){
			 
			if(Stmt.contentEquals("EndOfClass")){
				
				if((Stmt=brPrincipleClass.readLine())!=null){
					
					PrincipleClassNames[count++]=Stmt;
					principleClassNo++;
					methodCount=0;	
				}				
			}			
			else
			{
				PCMethods[principleClassNo][methodCount++]=new String(Stmt);
				PCNoOfMethods[principleClassNo]++;
			}
		 }		 
	}	 
	
 	inForPrincipleClass.close();    
}

public void markAssociations(BufferedWriter output, String viewType) throws Exception{
	
	association=new String[noOfRows][noOfColumns];	
	FileInputStream fstreamForView = new FileInputStream("InfoFiles/"+viewType+".txt");   
    DataInputStream inForMemberView = new DataInputStream(fstreamForView);
    BufferedReader brMemberView = new BufferedReader(new InputStreamReader(inForMemberView));

    	for(int iterMethod=0; iterMethod<noOfRows; iterMethod++) {
		    	for(int iterAttribute=0; iterAttribute<noOfColumns; iterAttribute++){
		    		association[iterMethod][iterAttribute]="0";		    		
		    	}
    	}
    	String Stmnt=null;
    	String preveousStmnt=null;
    	while((Stmnt=brMemberView.readLine())!=null){    		   
    			if(Stmnt.contentEquals(PrincipleClassNames[currentIndex]) && preveousStmnt!="StartOfMethod"){ // Read Class Name
    			   			
    					while((!(Stmnt=brMemberView.readLine()).contentEquals("EndOfClass")) && Stmnt!=null)
    					{
    						
    						if(Stmnt.contentEquals("StartOfMethod")){
    							
    								Stmnt=brMemberView.readLine();
    						   							
    								if(Stmnt==null)break;
    								
    								 for(int i=0; i<noOfRows; i++)
    								 {
    									if(Stmnt.contentEquals(PCMethods[currentIndex][i]))
    										
    									
    										while((!(Stmnt=brMemberView.readLine()).contentEquals("EndOfMethod") ) && Stmnt!=null   )
    		    	    					{
    										
    											for(int j=0; j<noOfColumns; j++)
    	        								{
    											 if(Stmnt.contentEquals(PCAttributes[currentIndex][j]))
    											 {
    												association[i][j]="1"; 
    											 }
    	        								}
    		    	    					}
        								
    								}
    							
    								}
    					}
    			}    			
    			preveousStmnt=Stmnt;
    	}
    	
		if(explorer.contentEquals("Conexp"))
		{
			placeConexpInput(output);
		}
		else if(explorer.contentEquals("Galicia"))
		{
			placeGaliciaInput(output);
		}


    

}
private void placeConexpInput(BufferedWriter output) throws IOException {
	
	
	output.write(";");
	
	for(int iter=0; iter<noOfColumns; iter++)
	{   
		if(PCAttributes[currentIndex][iter]!=null)
		{
			output.write(PCAttributes[currentIndex][iter]);
		}
		output.write(";");
	}
	
	output.newLine();
	output.newLine();
	for(int x=0; x<noOfRows; x++)
	{	    	
		output.write(PCMethods[currentIndex][x]);
	      output.write(";");
		for(int y=0; y<noOfColumns; y++)
		{    		
			output.write(association[x][y]);    		
			output.write(";");
		}    	
		output.newLine();
	}	
 	   
 	   
	output.close();
}
private void placeGaliciaInput(BufferedWriter output) throws IOException {
	 output.write("[Relational Context]\r"+viewType+"View\r[Binary Relation]\rPrincipleClass\r");
	   
	    //writing methods	    
	    for(int x=0; x<noOfRows; x++)
	    {
	    	output.write(PCMethods[currentIndex][x]);
	    	 output.write(" | ");
	    }
	    output.write("\r");	    
	    //writing Fields
	    for(int iter=0; iter<noOfColumns; iter++)
	    {    
	    	output.write(PCAttributes[currentIndex][iter]);    
	    	output.write(" | ");
	    }
	    
	    
	    //writing associations
	    output.write("\r");
	    for(int x=0; x<noOfRows; x++)
	    {
	   
	    	for(int y=0; y<noOfColumns; y++)
	    	{    		
	    		output.write(association[x][y]);    		
	    		output.write(" ");
	    	}    	
	    
	   
	    	output.write("\r");
	    }	
	    
	       output.write("[END Relational Context]");		
		   output.write("\r");		   

 	   
	output.close();
}
public void generateFundamentalViews(String outputFileName) throws Exception
{
	
	

	extractInfo();
    getPrincipleClassNamesAndMethods();
    getPrincipleClassAttributes("FundamentalView.txt");
    BufferedWriter [ ]output = new BufferedWriter[principleClassesCount];
    for(int i=0; i<principleClassesCount; i++)
    {
    	currentIndex=i;	    
    	noOfRows=PCNoOfMethods[i];
    	noOfColumns=PCNoOfAttribute[i];
    	if(noOfRows>0 && noOfColumns>0 )
    	{
    		String fileName=outputFileName.substring(0, outputFileName.indexOf(".")).concat("_"+PrincipleClassNames[i]+"_FundamentalView"+extension);
    		output[i]=new BufferedWriter(new FileWriter(fileName));
    		markAssociations(output[i], "FundamentalView");
    	}
    	
    	
   }
}
public void generateAssociationViews(String outputFileName) throws Exception
{
 	
 	   extractInfo();
       getPrincipleClassNamesAndMethods();
       getPrincipleClassAttributes("AssociationView.txt");
	   BufferedWriter [ ]output = new BufferedWriter[principleClassesCount];
	    for(int i=0; i<principleClassesCount; i++)
	    {
	    	currentIndex=i;	    	
	    	noOfRows=PCNoOfMethods[i];	    	
	    	noOfColumns=PCNoOfAttribute[i];
	    	if(noOfRows>0 && noOfColumns>0)
	    	{
	    		String fileName=outputFileName.substring(0, outputFileName.indexOf(".")).concat("_"+PrincipleClassNames[i]+"_AssociationView"+extension);
	    		output[i]=new BufferedWriter(new FileWriter(fileName));
	    		markAssociations( output[i], "AssociationView");
	    	}
	   }
}
public void generateInteractionViews(String outputFileName ) throws Exception
{
		
		extractInfo();
	 	getPrincipleClassNamesAndMethods();
    	getPrincipleClassAttributes("InteractionView.txt");
	    BufferedWriter [ ]output = new BufferedWriter[principleClassesCount];
	    for(int i=0; i<principleClassesCount; i++)
	    {
	    	currentIndex=i;	    
	    	noOfRows=PCNoOfMethods[i];
	    	noOfColumns=PCNoOfAttribute[i];
	    	if(noOfRows>0 && noOfColumns>0)
	    	{
	    		String fileName=outputFileName.substring(0, outputFileName.indexOf(".")).concat("_"+PrincipleClassNames[i]+"_InteractionView."+extension);
	    		output[i]=new BufferedWriter(new FileWriter(fileName));	    	
	    		markAssociations(output[i], "InteractionView");
	    	}
	   }
}
public void generateConexpInput(String []selectedFiles, int numFiles, String outputFileName){	try {
		
		PCEParser parser=new PCEParser();    	
		parser.parseClasses(selectedFiles, numFiles);
		explorer="Conexp";
		extension=".csv";
		viewType="Fundamental";
		generateFundamentalViews(outputFileName);
		viewType="Association";
		generateAssociationViews(outputFileName);
		viewType="Interaction";
		generateInteractionViews(outputFileName);
		
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}


}



public void generateGaliciaInput(String []selectedFiles, int numFiles, String outputFileName){
	
 try {
	 	PCEParser parser=new PCEParser();    	
		parser.parseClasses(selectedFiles, numFiles);    
		explorer="Galicia";
		extension=".rcf";
		viewType="Fundamental";
		generateFundamentalViews(outputFileName);
		viewType="Association";
		generateAssociationViews(outputFileName);
		viewType="Interaction";
		generateInteractionViews(outputFileName);

	
} catch (Exception e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}


}






}
